/***********************************************


	>	Author: SuperDian
	>	Mail: tech-sky@outlook.com
	>	Create Time: 2016年02月09日 星期二 17时02分43秒
	>	File Name: Deal.cc

***********************************************/
#include "Deal.h"

bool Deal::inside(char *str,char *str1,char *str2)
{
	int len = strlen(str);
	int len1= strlen(str1);
	int len2= strlen(str2);
	int i=0;
	for(int j=0;j<len1;j++)
	{
		if(str[i]==str1[j])
			i++;
		if(i==len) return true;
	}
	i=0;
	for(int j=0;j<len2;j++)
	{
		if(str[i]==str2[j])
			i++;
		if(i==len) return true;
	}
	return false;
}

void Deal::Perform(char *recv,char *send)
{

	Document doc;
	doc.Parse(recv);
	time_t tt = time(NULL);
	tm* t = localtime(&tt);
	if(!doc.HasMember("method"))
	{
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Client: %s\n",recv);
		sprintf(send,"{\"method\":\"unknown_command\"}");
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Server: %s\n",send);
	}
	else if(strcmp(doc["method"].GetString(),"SayHi")==0)
	{
		SayHi(send);
	}
	else if(strcmp(doc["method"].GetString(),"import_student")==0)
	{
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Client: %s\n",recv);
		import_student(doc,send);
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Server: %s\n",send);
	}
	else if(strcmp(doc["method"].GetString(),"import_room")==0)
	{
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Client: %s\n",recv);
		import_room(doc,send);
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Server: %s\n",send);
	}
	else if(strcmp(doc["method"].GetString(),"delete_room")==0)
	{
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Client: %s\n",recv);
		delete_room(doc,send);
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Server: %s\n",send);
	}
	else if(strcmp(doc["method"].GetString(),"delete_student")==0)
	{
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Client: %s\n",recv);
		delete_student(doc,send);
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Server: %s\n",send);
	}
	else if(strcmp(doc["method"].GetString(),"show_student")==0)
	{
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Client: %s\n",recv);
		show_student(doc,send);
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Server: %s\n",send);
	}
	else if(strcmp(doc["method"].GetString(),"show_room")==0)
	{
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Client: %s\n",recv);
		show_room(doc,send);
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Server: %s\n",send);
	}
	else if(strcmp(doc["method"].GetString(),"search_student")==0)
	{
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Client: %s\n",recv);
		search_student(doc,send);
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Server: %s\n",send);
	}
	else if(strcmp(doc["method"].GetString(),"get_room")==0)
	{
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Client: %s\n",recv);
		get_room(doc,send);
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Server: %s\n",send);
	}
	else if(strcmp(doc["method"].GetString(),"get_student")==0)
	{
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Client: %s\n",recv);
		get_student(doc,send);
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Server: %s\n",send);
	}
	else
	{
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Client: %s\n",recv);
		sprintf(send,"{\"method\":\"unknown_command\"}");
		printf("[%02d:%02d:%02d]:",t->tm_hour,t->tm_min,t->tm_sec);
		printf("Server: %s\n",send);
	}

}

/*
客户端发来的消息:
{
	"method":"import_student",
	"student_name":"",
	"student_number":"",
	"student_sex":"",
	"student_room":"",
	"student_note":""
}
服务端返回的消息:
{
	"method":"import_student",
	"result":["success","failed"]
}
*/
void Deal::import_student(Document &doc,char *send)
{
	try
	{
		Document dStudent,dRoom;
		Pointer("/student_name").Set(dStudent,doc["student_name"].GetString());
		Pointer("/student_number").Set(dStudent,doc["student_number"].GetString());
		Pointer("/student_sex").Set(dStudent,doc["student_sex"].GetString());
		Pointer("/student_room").Set(dStudent,doc["student_room"].GetString());
		Pointer("/student_note").Set(dStudent,doc["student_note"].GetString());

		char filename1[100];
		sprintf(filename1, "./data/student/%s.json",doc["student_number"].GetString());
		char filename2[100];
		sprintf(filename2,"./data/room/%s.json",doc["student_room"].GetString());
		JsonFile::jsonRead(filename2,dRoom);


		Value* room_member = GetValueByPointer(dRoom,"/room_member");
		Value val(doc["student_number"].GetString(),dRoom.GetAllocator());
		room_member->PushBack(val,dRoom.GetAllocator());
		GetValueByPointer(dRoom,"/room_people")->SetInt(GetValueByPointer(dRoom,"/room_people")->GetInt()+1);

		if(GetValueByPointer(dRoom,"/room_member/0")->IsNull())
			EraseValueByPointer(dRoom,"/room_member/0");

		if(JsonFile::jsonPrettyWrite(filename1,dStudent)&&JsonFile::jsonPrettyWrite(filename2,dRoom))
			sprintf(send,"{\"method\":\"import_student\",\"result\":\"success\"}");
		else
			sprintf(send,"{\"method\":\"import_student\",\"result\":\"failed\"}");

	}
	catch(...)
	{
		sprintf(send,"{\"method\":\"import_student\",\"result\":\"failed\"}");
	}
}
/*
客户端发来的消息:
{
	"method":"import_room",
	"room_name":"",
	"room_sex":"",
	"room_size":4,
	"room_note":""
}
服务器返回的消息:
{
	"method":"import_room",
	"result":["success","failed"]
}
*/
void Deal::import_room(Document &doc,char *send)
{
	try
	{
		Document d;
		Pointer("/room_name").Set(d,doc["room_name"].GetString());
		Pointer("/room_sex").Set(d,doc["room_sex"].GetString());
		Pointer("/room_size").Set(d,doc["room_size"].GetInt());
		Pointer("/room_people").Set(d,0);
		Pointer("/room_member/0").Create(d);
		Pointer("/room_note").Set(d,doc["room_note"].GetString());
		char filename[100];
		sprintf(filename,"data/room/%s.json",doc["room_name"].GetString());
		if(JsonFile::jsonPrettyWrite(filename,d))
			sprintf(send,"{\"method\":\"import_room\",\"result\":\"success\"}");
		else
			sprintf(send,"{\"method\":\"import_room\",\"result\":\"failed\"}");
	}
	catch(...)
	{
		sprintf(send,"{\"method\":\"import_room\",\"result\":\"failed\"}");
	}
}
/*
客户端
{
	"method":"delete_student",
	"student_number":"",
	"student_room":""
}
服务端
{
	"method":"delete_student",
	"result":["success","failed"]
}
*/
void Deal::delete_student(Document &doc,char *send)
{	try{
		char fileStudent[100],fileRoom[100];
		sprintf(fileStudent,"data/student/%s.json",doc["student_number"].GetString());
	//	sprintf(fileRoom,"data/room/%s.json",doc["student_room"].GetString());
		Document d;
		JsonFile::jsonRead(fileStudent,d);
		sprintf(fileRoom,"data/room/%s.json",d["student_room"].GetString());
		JsonFile::jsonRead(fileRoom,d);
		if(!remove(fileStudent))
		{
			Value* val = GetValueByPointer(d,"/room_member");
			int i=0;
			for(Value::ConstValueIterator itr = val->Begin(); itr != val->End();i++,itr++)
			{
			//	printf("----%s----%s----\n",doc["student_number"].GetString(),itr->GetString());
				if(strcmp(doc["student_number"].GetString(),itr->GetString())==0)
				{
					GetValueByPointer(d,"/room_member")->Erase(itr);
				//	printf("----test point1---\n");
					break;
				}
			}
			GetValueByPointer(d,"/room_people")->SetInt(GetValueByPointer(d,"/room_people")->GetInt()-1);
			if(JsonFile::jsonPrettyWrite(fileRoom,d))
				sprintf(send,"{\"method\":\"delete_student\",\"result\":\"success\"}");
			else
				sprintf(send,"{\"method\":\"delete_student\",\"result\":\"failed\"}");
		}
	}
	catch(...)
	{
		sprintf(send,"{\"method\":\"delete_student\",\"result\":\"failed\"}");
	}
}
/*
客户端
{
	"method":"delete_room",
	"room_name":""
}
服务端
{
	"method":"delete_room",
	"result":["success","failed"]
}
*/
void Deal::delete_room(Document &doc,char *send)
{
	try
	{
		char fileRoom[100];
		sprintf(fileRoom,"data/room/%s.json",doc["room_name"].GetString());
		Document droom,dstudent;

		JsonFile::jsonRead(fileRoom,droom);
		if(!remove(fileRoom))
		{
			if(Value* room_member = GetValueByPointer(droom,"/room_member"))
			{
				for(Value::ConstValueIterator itr = room_member->Begin(); itr != room_member->End();++itr)
				{
					if(!itr->IsNull())
					{
						char fileStudent[100];
						sprintf(fileStudent,"data/student/%s.json",itr->GetString());
						JsonFile::jsonRead(fileStudent,dstudent);
						Pointer("/student_room").Set(dstudent,"undetermined");
					}
				}
			}
		}
	}
	catch(...)
	{
		sprintf(send,"{\"method\":\"delete_room\",\"result\":\"failed\"}");
		return;
	}
		sprintf(send,"{\"method\":\"delete_room\",\"result\":\"success\"}");
}
/*
客户端
{
	"method":"show_student",
	"student_sex":["boy","girl","all"]

}
服务端
{
	"method":"show_student",
	"result":[]
}
*/
void Deal::show_student(Document &doc,char *send)
{
	try
	{
		char value[100];
		sprintf(value,"%s",doc["student_sex"].GetString());
		Document d;
		Pointer("/method").Set(d,"show_student");
		Pointer("/result/0").Create(d);
		Document tmp;
		Pointer("/method").Set(tmp,"show_student");
		char list[100]="data/student";
		if(CBrowse::getJsonFiles(tmp,list))
		{
			Value* val = GetValueByPointer(tmp,"/result");
			if(strcmp(value,"boy")==0)
			{
				for(Value::ConstValueIterator itr = val->Begin(); itr != val->End();++itr)
				{
					char fileStu[300];
					sprintf(fileStu,"data/student/%s",itr->GetString());
					Document d_stu;
					JsonFile::jsonRead(fileStu,d_stu);
					if(strcmp(GetValueByPointer(d_stu,"/student_sex")->GetString(),"boy")==0)
					{
						Value tmp_value(GetValueByPointer(d_stu,"/student_number")->GetString(),d.GetAllocator());
						GetValueByPointer(d,"/result")->PushBack(tmp_value,d.GetAllocator());
					}
				}
			}
			if(strcmp(value,"girl")==0)
			{
				for(Value::ConstValueIterator itr = val->Begin(); itr != val->End();++itr)
				{
					char fileStu[300];
					sprintf(fileStu,"data/student/%s",itr->GetString());
					Document d_stu;
					JsonFile::jsonRead(fileStu,d_stu);
					if(strcmp(GetValueByPointer(d_stu,"/student_sex")->GetString(),"girl")==0)
					{
						Value tmp_value(GetValueByPointer(d_stu,"/student_number")->GetString(),d.GetAllocator());
						GetValueByPointer(d,"/result")->PushBack(tmp_value,d.GetAllocator());
					}
				}
			}
			if(strcmp(value,"all")==0)
			{
				for(Value::ConstValueIterator itr = val->Begin(); itr != val->End();++itr)
				{
					char fileStu[300];
					sprintf(fileStu,"data/student/%s",itr->GetString());
					Document d_stu;
					JsonFile::jsonRead(fileStu,d_stu);
					Value tmp_value(GetValueByPointer(d_stu,"/student_number")->GetString(),d.GetAllocator());
					GetValueByPointer(d,"/result")->PushBack(tmp_value,d.GetAllocator());
				}
			}
		}
		if(GetValueByPointer(d,"/result/0")->IsNull())
			EraseValueByPointer(d,"/result/0");
		StringBuffer buffer;
		Writer<StringBuffer> writer(buffer);
		d.Accept(writer);
		strcpy(send,buffer.GetString());
	}
	catch(...)
	{

	}
}
/*
客户端
{
	"method":"show_room",
	"room_sex":["boy","girl","all"],
	"room_status":["all","avilable"]
}
服务端
{
	"method":"show_room",
	"result":[]
}
*/
void Deal::show_room(Document &doc,char *send)
{
	try
	{
		char value[100];
		sprintf(value,"%s",doc["room_sex"].GetString());
		Document d;
		Pointer("/method").Set(d,"show_room");
		Pointer("/result/0").Create(d);
		Document tmp;
		Pointer("/method").Set(tmp,"show_room");
		char list[100]="data/room";
		if(CBrowse::getJsonFiles(tmp,list))
		{
			Value* val = GetValueByPointer(tmp,"/result");
			if(strcmp(value,"boy")==0)
			{
				for(Value::ConstValueIterator itr = val->Begin(); itr != val->End();++itr)
				{
					char fileRoom[300];
					sprintf(fileRoom,"data/room/%s",itr->GetString());
					Document d_room;
					JsonFile::jsonRead(fileRoom,d_room);
					if(strcmp(GetValueByPointer(d_room,"/room_sex")->GetString(),"boy")==0)
					{
						Value tmp_value(GetValueByPointer(d_room,"/room_name")->GetString(),d.GetAllocator());
						GetValueByPointer(d,"/result")->PushBack(tmp_value,d.GetAllocator());
					}
				}
			}
			if(strcmp(value,"girl")==0)
			{
				for(Value::ConstValueIterator itr = val->Begin(); itr != val->End();++itr)
				{
					char fileRoom[300];
					sprintf(fileRoom,"data/room/%s",itr->GetString());
					Document d_room;
					JsonFile::jsonRead(fileRoom,d_room);
					if(strcmp(GetValueByPointer(d_room,"/room_sex")->GetString(),"girl")==0)
					{
						Value tmp_value(GetValueByPointer(d_room,"/room_name")->GetString(),d.GetAllocator());
						GetValueByPointer(d,"/result")->PushBack(tmp_value,d.GetAllocator());
					}
				}
			}
			if(strcmp(value,"all")==0)
			{
				for(Value::ConstValueIterator itr = val->Begin(); itr != val->End();++itr)
				{
					char fileRoom[300];
					sprintf(fileRoom,"data/room/%s",itr->GetString());
					Document d_room;
					JsonFile::jsonRead(fileRoom,d_room);
					Value tmp_value(GetValueByPointer(d_room,"/room_name")->GetString(),d.GetAllocator());
					GetValueByPointer(d,"/result")->PushBack(tmp_value,d.GetAllocator());
				}
			}
		}
		if(GetValueByPointer(d,"/result/0")->IsNull())
			EraseValueByPointer(d,"/result/0");
		StringBuffer buffer;
		Writer<StringBuffer> writer(buffer);
		d.Accept(writer);
		strcpy(send,buffer.GetString());
	}
	catch(...)
	{

	}
}
void Deal::get_student(Document &doc,char *send)
{
	try
	{
		char fileName[300];
		sprintf(fileName,"data/student/%s.json",doc["student_number"].GetString());
//		printf("FileName: %s\n",fileName);
		JsonFile::jsonRead(fileName,send);
	}
	catch(...)
	{

	}
}
void Deal::get_room(Document &doc,char *send)
{
	try
	{
		char fileName[300];
		sprintf(fileName,"data/room/%s.json",doc["room_name"].GetString());
//		printf("FileName: %s\n",fileName);
		JsonFile::jsonRead(fileName,send);
	}
	catch(...)
	{

	}
}
/*
客户端
{
	"method":"search_student",
	"student_info":""
}
服务端
{
	"method":"search_student",
	"result":["201413137017","","","",""]
}
*/
void Deal::search_student(Document &doc,char *send)
{
	try
	{
		char value[100];
		sprintf(value,"%s",doc["student_sex"].GetString());
		Document d;
		Pointer("/method").Set(d,"search_student");
		Pointer("/result/0").Create(d);
		Document tmp;
		Pointer("/method").Set(tmp,"search_student");
		char list[100]="data/student";
		if(CBrowse::getJsonFiles(tmp,list))
		{
			Value* val = GetValueByPointer(tmp,"/result");
			for(Value::ConstValueIterator itr = val->Begin(); itr != val->End();++itr)
			{
				char fileStu[300];
				sprintf(fileStu,"data/student/%s",itr->GetString());
				Document d_stu;
				JsonFile::jsonRead(fileStu,d_stu);
				if(strcmp(value,"boy")==0)
				{
					if(strcmp(GetValueByPointer(d_stu,"/student_sex")->GetString(),"boy")==0)
					{
						char stu_info[1000];
						char str1[1000],str2[1000];
						strcpy(stu_info,GetValueByPointer(doc,"/student_info")->GetString());
						strcpy(str1,GetValueByPointer(d_stu,"/student_name")->GetString());
						strcpy(str2,GetValueByPointer(d_stu,"/student_number")->GetString());
						if(inside(stu_info,str1,str2))
						{
							Value tmp_value(GetValueByPointer(d_stu,"/student_number")->GetString(),d.GetAllocator());
							GetValueByPointer(d,"/result")->PushBack(tmp_value,d.GetAllocator());
						}
					}

				}
				else if(strcmp(value,"girl")==0)
				{

					if(strcmp(GetValueByPointer(d_stu,"/student_sex")->GetString(),"girl")==0)
					{
						char stu_info[1000];
						char str1[1000],str2[1000];
						strcpy(stu_info,GetValueByPointer(doc,"/student_info")->GetString());
						strcpy(str1,GetValueByPointer(d_stu,"/student_name")->GetString());
						strcpy(str2,GetValueByPointer(d_stu,"/student_number")->GetString());

						if(inside(stu_info,str1,str2))
						{
							Value tmp_value(GetValueByPointer(d_stu,"/student_number")->GetString(),d.GetAllocator());
							GetValueByPointer(d,"/result")->PushBack(tmp_value,d.GetAllocator());
						}
					}
				}
				else if(strcmp(value,"all")==0)
				{

					char stu_info[1000];
					char str1[1000],str2[1000];
					strcpy(stu_info,GetValueByPointer(doc,"/student_info")->GetString());
					strcpy(str1,GetValueByPointer(d_stu,"/student_name")->GetString());
					strcpy(str2,GetValueByPointer(d_stu,"/student_number")->GetString());

					if(inside(stu_info,str1,str2))
					{
						Value tmp_value(GetValueByPointer(d_stu,"/student_number")->GetString(),d.GetAllocator());
						GetValueByPointer(d,"/result")->PushBack(tmp_value,d.GetAllocator());
					}
				}

			}
		}
		if(GetValueByPointer(d,"/result/0")->IsNull())
			EraseValueByPointer(d,"/result/0");
		StringBuffer buffer;
		Writer<StringBuffer> writer(buffer);
		d.Accept(writer);
		strcpy(send,buffer.GetString());
	}
	catch(...)
	{
		printf("search student error\n");
		sprintf(send,"{\"method\":\"search_student\",\"result\":\"failed\"}");
	}
}
/*
客户端
{
	"method":"SayHi"
}
服务端
{
	"method":"SayHi"
}
*/
void Deal::SayHi(char *send)
{
	sprintf(send,"{\"method\":\"SayHi\"}");
}
